use std::collections::{HashMap, HashSet};
-use std::ffi::{OsStr, OsString};
-use std::path::PathBuf;
+use std::ffi::OsStr;
+use std::path::{Path, PathBuf};
use semver::Version;
use core::{PackageId, Package, Target};
-use util::{self, CargoResult, Config, ProcessBuilder, process};
+use util::{self, CargoResult, Config, ProcessBuilder, process, join_paths};
/// A structure returning the result of a compilation.
pub struct Compilation<'cfg> {
config: &'cfg Config,
}
-#[derive(Clone, Debug)]
-pub enum CommandType {
- Rustc,
- Rustdoc,
-
- /// The command is to be executed for the target architecture.
- Target(OsString),
-
- /// The command is to be executed for the host architecture.
- Host(OsString),
-}
-
impl<'cfg> Compilation<'cfg> {
pub fn new(config: &'cfg Config) -> Compilation<'cfg> {
Compilation {
}
/// See `process`.
- pub fn rustc_process(&self, pkg: &Package) -> CargoResult<ProcessBuilder> {
- self.process(CommandType::Rustc, pkg)
+ pub fn rustc_process(&self, pkg: &Package, host_dylib_path: &Path)
+ -> CargoResult<ProcessBuilder> {
+ self.fill_env(try!(self.config.rustc()).process(), pkg, Some(host_dylib_path))
}
/// See `process`.
- pub fn rustdoc_process(&self, pkg: &Package)
+ pub fn rustdoc_process(&self, pkg: &Package, host_dylib_path: Option<&Path>)
-> CargoResult<ProcessBuilder> {
- self.process(CommandType::Rustdoc, pkg)
+ self.fill_env(process(&*try!(self.config.rustdoc())), pkg, host_dylib_path)
}
/// See `process`.
pub fn target_process<T: AsRef<OsStr>>(&self, cmd: T, pkg: &Package)
-> CargoResult<ProcessBuilder> {
- self.process(CommandType::Target(cmd.as_ref().to_os_string()), pkg)
+ self.fill_env(process(cmd), pkg, None)
}
/// See `process`.
- pub fn host_process<T: AsRef<OsStr>>(&self, cmd: T, pkg: &Package)
+ pub fn host_process<T: AsRef<OsStr>>(&self, cmd: T, pkg: &Package, host_dylib_path: &Path)
-> CargoResult<ProcessBuilder> {
- self.process(CommandType::Host(cmd.as_ref().to_os_string()), pkg)
+ self.fill_env(process(cmd), pkg, Some(host_dylib_path))
}
/// Prepares a new process with an appropriate environment to run against
///
/// The package argument is also used to configure environment variables as
/// well as the working directory of the child process.
- pub fn process(&self, cmd: CommandType, pkg: &Package)
- -> CargoResult<ProcessBuilder> {
- let mut search_path = vec![];
-
- // Add -L arguments, after stripping off prefixes like "native=" or "framework=".
- for dir in self.native_dirs.iter() {
- let dir = match dir.to_str() {
- Some(s) => {
- let mut parts = s.splitn(2, '=');
- match (parts.next(), parts.next()) {
- (Some("native"), Some(path)) |
- (Some("crate"), Some(path)) |
- (Some("dependency"), Some(path)) |
- (Some("framework"), Some(path)) |
- (Some("all"), Some(path)) => path.into(),
- _ => dir.clone(),
+ fn fill_env(&self, mut cmd: ProcessBuilder, pkg: &Package, host_dylib_path: Option<&Path>)
+ -> CargoResult<ProcessBuilder> {
+
+ let mut search_path = if let Some(host_dylib_path) = host_dylib_path {
+ // When invoking a tool, we need the *host* deps directory in the dynamic
+ // library search path for plugins and such which have dynamic dependencies.
+ vec![host_dylib_path.to_path_buf()]
+ } else {
+ let mut search_path = vec![];
+
+ // Add -L arguments, after stripping off prefixes like "native=" or "framework=".
+ for dir in self.native_dirs.iter() {
+ let dir = match dir.to_str() {
+ Some(s) => {
+ let mut parts = s.splitn(2, '=');
+ match (parts.next(), parts.next()) {
+ (Some("native"), Some(path)) |
+ (Some("crate"), Some(path)) |
+ (Some("dependency"), Some(path)) |
+ (Some("framework"), Some(path)) |
+ (Some("all"), Some(path)) => path.into(),
+ _ => dir.clone(),
+ }
}
- }
- None => dir.clone(),
- };
- search_path.push(dir);
- }
- search_path.push(self.root_output.clone());
- search_path.push(self.deps_output.clone());
- search_path.extend(util::dylib_path().into_iter());
- let search_path = try!(util::join_paths(&search_path,
- util::dylib_path_envvar()));
- let mut cmd = match cmd {
- CommandType::Rustc => try!(self.config.rustc()).process(),
- CommandType::Rustdoc => process(&*try!(self.config.rustdoc())),
- CommandType::Target(ref s) |
- CommandType::Host(ref s) => process(s),
+ None => dir.clone(),
+ };
+ search_path.push(dir);
+ }
+ search_path.push(self.root_output.clone());
+ search_path.push(self.deps_output.clone());
+ search_path
};
+
+ search_path.extend(util::dylib_path().into_iter());
+ let search_path = try!(join_paths(&search_path, util::dylib_path_envvar()));
+
cmd.env(util::dylib_path_envvar(), &search_path);
if let Some(env) = self.extra_env.get(pkg.package_id()) {
for &(ref k, ref v) in env {
use self::job::{Job, Work};
use self::job_queue::JobQueue;
-pub use self::compilation::{Compilation, CommandType};
+pub use self::compilation::Compilation;
pub use self::context::{Context, Unit};
pub use self::layout::{Layout, LayoutProxy};
pub use self::custom_build::{BuildOutput, BuildMap, BuildScripts};
fn prepare_rustc(cx: &Context,
crate_types: Vec<&str>,
unit: &Unit) -> CargoResult<ProcessBuilder> {
- let mut base = try!(process(CommandType::Rustc, unit.pkg, cx));
+ let mut base = try!(cx.compilation.rustc_process(unit.pkg, cx.host_dylib_path()));
build_base_args(cx, &mut base, unit, &crate_types);
build_plugin_args(&mut base, cx, unit);
try!(build_deps_args(&mut base, cx, unit));
fn rustdoc(cx: &mut Context, unit: &Unit) -> CargoResult<Work> {
- let mut rustdoc = try!(process(CommandType::Rustdoc, unit.pkg, cx));
+ let mut rustdoc = try!(cx.compilation.rustdoc_process(unit.pkg, Some(cx.host_dylib_path())));
rustdoc.arg(&root_path(cx, unit))
.cwd(cx.config.cwd())
.arg("--crate-name").arg(&unit.target.crate_name());
}
}
-pub fn process(cmd: CommandType, pkg: &Package,
- cx: &Context) -> CargoResult<ProcessBuilder> {
- // When invoking a tool, we need the *host* deps directory in the dynamic
- // library search path for plugins and such which have dynamic dependencies.
- let mut search_path = util::dylib_path();
- search_path.push(cx.host_dylib_path().to_path_buf());
-
- // We want to use the same environment and such as normal processes, but we
- // want to override the dylib search path with the one we just calculated.
- let search_path = try!(join_paths(&search_path, util::dylib_path_envvar()));
- let mut cmd = try!(cx.compilation.process(cmd, pkg));
- cmd.env(util::dylib_path_envvar(), &search_path);
- Ok(cmd)
-}
-
fn envify(s: &str) -> String {
s.chars()
.flat_map(|c| c.to_uppercase())